﻿using System;
using System.ComponentModel;
using ProxyViewModel.Messaging;

namespace ProxyViewModel {
	public class ProxyViewModelFactory {
		private static readonly Generator _generator = new Generator();

		/// <summary>
		/// Creates an observable ViewModel.
		/// </summary>
		/// <typeparam name="T">ViewModel Type</typeparam>
		/// <param name="constructorParameters">Constructor parameters</param>
		/// <returns>ViewModel observable instance</returns>
		public static T CreateProxyViewModel<T>(params object[] constructorParameters) where T : class {
			Type type = _generator.GetProxy<T>(constructorParameters);
			T obj =  (T)Activator.CreateInstance(type, constructorParameters);
			MessengerManager.RegisterViewModel(obj);
			return obj;
		}

		/// <summary>
		/// Creates an observable ViewModel
		/// </summary>
		/// <typeparam name="T">Type of the ViewModel that will be created</typeparam>
		/// <param name="parentViewModel">Parent ViewModel. The reference is passed so that child view model can invalidate commands on the parent ViewModel</param>
		/// <param name="constructorParameters">constructor parameters to the view model</param>
		/// <returns>ViewModel observable instance</returns>
		public static T CreateProxyViewModelWithParentViewModel<T>(object parentViewModel, params object[] constructorParameters)
			where T : class {
			Type type = _generator.GetProxy<T>(constructorParameters);
			T resultViewModel = (T)Activator.CreateInstance(type, constructorParameters);

			if (!(parentViewModel is INotifyPropertyChanged)) {
				throw new ArgumentException("parentViewModel must be of type that implements INotifyPropertyChanged");
			}
			((IContainedViewModel)resultViewModel).SetParentViewModel(parentViewModel);
			MessengerManager.RegisterViewModel(resultViewModel);
			return resultViewModel;
		}
	}
}
